Base64
base64是一种基于64个可打印字符来表示二进制数据的表示方法.严格来说它只能算作一种编码方式.
Base64编码之所以称为Base64,是因为其使用64个字符来对任意数据进行编码,同理有Base32、Base16编码
作用:
1, 由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法.
2, 使用SMTP协议 (Simple Mail Transfer Protocol 简单邮件传输协议)来发送邮件。因为这个协议是基于文本的协议,所以如果邮件中包含一幅图片,我们知道图片的存储格式是二进制数据(binary data),而非文本格式,我们必须将二进制的数据编码成文本格式,这时候Base 64 Encoding就派上用场了.
3, 通过base64将ASCII不可见字符转换为可见字符
使用:
1 | //编码 |
MD5
MD5(消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.
特点:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的(32摘要)。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞(难逆向):已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
作用
1, 数字签名, 当我们传递敏感信息时,可以为利用MD5+时间戳+盐 为消息添加唯一的数字签名,当服务端获得数据后,用相同算法再次签名.进行比较 若不一致 则数据遭到篡改.
2, 文件验证, 我们在下载文件时,由于复杂的网络环境,我们下载的文件可能会有内容丢失或篡改的可能性.(例如我们从服务器获取的H5文件遭到了JS注入),利用MD5可以有效防止这些事情的发生.
同类算法
SHA-1:
会产生一个160位的消息摘要,SHA-1的安全性在2000年以后已经不被大多数的加密场景所接受。2017年荷兰密码学研究小组CWI和Google正式宣布攻破了SHA-1.
SHA-2:
2001年发布,包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。虽然至今尚未出现对SHA-2有效的攻击,它的算法跟SHA-1基本上仍然相似;因此有些人开始发展其他替代的散列算法。
SHA-3:
2015年正式发布,SHA-3并不是要取代SHA-2,因为SHA-2目前并没有出现明显的弱点。由于对MD5出现成功的破解,以及对SHA-0和SHA-1出现理论上破解的方法,NIST感觉需要一个与之前算法不同的,可替换的加密散列算法,也就是现在的SHA-3。
实现
这里是对字符串的散列计算,若对文件则需要先读取文件流再去散列.
需要: import <CommonCrypto/CommonDigest.h>
MD5
1 | - (NSString *)md5String { |
SHA-1:
1 | - (NSString *)sha1String { |
SHA256:
1 | - (NSString *)sha256String { |
SHA512:
1 | - (NSString *)sha512String { |
SHA3:
需要在github上下载keccak代码包 :https://github.com/gvanas/KeccakCodePackage
大文件的计算:
这里以MD5为例:
1 | #define FileHashDefaultChunkSizeForReadingData 4096 |
对于其他的算法文件加密方式也是这样的,它们都是由CommonCrypto库提供的.
HMAC散列计算(加盐)
HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。
HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法,有些类似对称加密,但是是不可逆的那种~.
以MD5为例:
1 | - (NSString *)hmacMD5StringWithKey:(NSString *)key { |
AES(对称加密)
简介
美国国家标准技术研究所在2001年发布了高级加密标准(AES)。
AES是基于数据块的加密方式,
即,每次处理的数据是一块(16字节),当数据不是16字节的倍数时填充,
这就是所谓的分组密码(区别于基于比特位的流密码),16字节是分组长度。AES在软件及硬件上都能快速地加解密,相对来说较易于实现,
实现
在使用AES时要配置几个加密参数,只有都一致才能使 客户端与服务端 结果一致.
参数配置
密钥长度
key常见的长度有三种:128、192和256 bits
加密模式
AES属于块加密(Block Cipher),块加密中有CBC、ECB、CTR、OFB、CFB等几种工作模式.
ECB
是一种基础的加密方式,AES默认没收,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文.
CBC
这个模式是链式的,后一块需要前一块做基础,第一块需要一个需要初始化向量IV做基础.
相同的输入产生不同的输出.
能看到的数据是“明文+IV”或“明文+前一个密文”的乱码,所以能隐藏明文.
所以加密/解密 需要: 明文/密文 + 秘钥 + 初始向量参数
填充方式
因为AES的算法是把明文分组再处理的,他要求每个分组(16字节)是“满”的,即明文长度必须被16字节整除.
所以明文最后不足的16字节的要先进行数据填充,把不足16字节的最后一组补成16字节.
CFB,OFB和CTR模式由于与key进行加密操作的是上一块加密后的密文,因此不需要对最后一段明文进行填充.
在iOS SDK中提供了PKCS7Padding.
初始向量
正如在CBC模式哪里介绍的,开始加密时,从哪里开始就是初始向量,如不设置则系统默认为0;
代码
1 | NSString *const kInitVector = @"初始向量"; |
RSA
原理
数学基础
任意给定正整数n,请问在小于等于n的正整数之中,有多少个与n构成互质的数.计算这个值的函数为 欧拉函数: 如: φ(8) = 4.
若n为质数 则: φ(n) = n-1 原理3
若n为质数的n次方 则: φ(p^k) = p^k - p^(k-1)
若n为两个互质整数之积 则: φ(p1 p2) = φ(p1)φ(p2) 原理1
若正整数 a和n互质 则: a^φ(n) 被n除的余数为1 则: a^φ(n) %n=1 欧拉定理
若正整数a和质数p互质 则: a^p-1 %p=1 //费马小定理
若正整数a和n互质,则一定可以找到正整数b 使: ab%n=1, b为a的模反元素. *原理2
秘钥生成
1, 随机生成两个不等质数p和q 如 p=61 q=53
2, 求出pq乘积n n=p q= 6153=3233.
这里n的长度即为,秘钥长度,如3233为二进制12位,RSA秘钥一般为1024位.
3, 计算φ(n)
根据 原理1 φ(n) = φ(p)φ(q) = (p-1)(q-1) = 3120
4, 随机选择一个整数e 条件为 1<e<φ(n) 且 e与φ(n)互质
假如选择 17
5, 获取e对于φ(n)的模反元素d
ed%φ(n)=1 —> ed -1 = kφ(n) —> 17d + 3120k = 1
通过扩展欧几里德算法 可得到一组整数解 d=2753 k=-15
6, 这里 n和e 为公钥 n和d 为私钥
加密(此处为公钥加密 n e)
对明文信息m 加密 注意:m为正整数,且m须小于n
m^e % n = c
这里的c就是加密后得到的密文
65^17 % 3233 = 2790 这里2790就是加密后的密文
解密(n d)
解密原理
解密规则为: c^d %n = m
因为加密过程为: m^e % n = c —> c = m^e - kn
若想证明解密规则成立 则等同于证明 (m^e - kn)^d % n = m 成立
(m^e - kn)^d % n = m —> m^ed % n = m
由于在制作公私钥 的第5步 所以:
ed%φ(n)=1 —> ed = hφ(n)+1
将ed代入须证明公式:
m^ed % n = m —> m^hφ(n)+1 % n = m
若m n 互质
m^hφ(n)+1 % n = m —> ((m^φ(n))^h * m) % n = m
由于欧拉定理 m^φ(n) %n=1可得
((m^φ(n))^h m) % n = m —> (1^h m) % n = m 则解密公式成立
若m n 不互质
因为制作公私钥 的第1步 n = p * q
因为加密方法 m^e % n = c , 且因 m<n(这里是在制作时要求的) 所以 c肯定不为0 由此可得 m 与 n 不为互质关系.
由于 n = pq 且 pq互质 所以 n有且只有 p q 两个因子. 然而 m n有公因子 所以 m n 的公因子 必定为 q或p的整数倍. 所以 m = kp 或 kq
以 m=kp为例 因为上面描述的关系 m
由欧拉定理得:m^φ(q) % q = 1
—> 由于q为质数 —> m^q-1 % q = 1
–> (kp)^q-1 % q = 1
因为 k与q互质 p与q互质 –> ((kp)^q-1 * kp)%q = kp
进一步可以确定该式成立: (((kp)^h(p-1)(q-1)) * kp)%q = kp
因为p为质数 h为任一整数
由原理1和原理3(((kp)^h(p-1)(q-1)) * kp)%q = kp
—> (kp)^hφ(n)+1 %q=kp
由于 ed%φ(n)=1,且m=kp 所以将h匹配为合适的值得 (kp)^ed %q = kp
—> (m)^ed = tq +m
t为整数.
两侧同除m得: (m)^ed-1 = tq/m +1
由于ed为整数,m为整数 故tq/m为整数. 因q与m互质 所以t为m的整数倍 –> t = yp —> m^ed = yn+m
—> m^ed % n = m
由于加密方式 m^e % n = c
—> c^d % n = m
安全性讨论
若想破解RSA 则需要在已知 n e的情况下 求 d 因为
因为 ed%φ(n)=1 所以需知道 φ(n)
因为 φ(n) = (p-1)(q-1) 所以需求得 qp
因为 qp=n 所以得将n因式分解
而因式分解是十分困难的 特别是对于 特大整数的因式分解. 由于 名文m 需小于 秘钥长度n 所以常用来加密 对称加密的秘钥.
iOS实现
参考链接:iOS中使用RSA加密
在iOS中使用RSA加密解密 需要使用到.der 和 .p12 后缀格式文件.
.p12 格式文件是用来加密的 私钥
.der 格式文件用来解密的 公钥
添加动态库 Security.framework
具体实现太长,我汇总了一个类 感兴趣可以下下来看看 如果帮到你 点个Star鼓励一蛤~github链接